一个物理碰撞特效的例子

(import (rnrs)
	(gles gles1)
	(glut glut)
  (dharmalab misc limit-call-rate)
	(agave glamour misc)
	(agave glamour window)
	(box2d-lite util math)
	(box2d-lite vec)
	(box2d-lite mat)
	(box2d-lite body)
	(box2d-lite joint)
	(box2d-lite world)
  (surfage s27 random-bits))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define scale
    (case (machine-type)
      ((arm32le) 1 )
      ((a6nt i3nt)  1)
      ((a6osx i3osx)  2 )
      ((a6le i3le) 1 )))

(initialize-glut)

(window
  (size 800 600)
	(title "Box2d Lite - Dominos")
	(reshape (width height)
		 (lambda (w h)
       (glViewport 0 0  (* w scale)  (* scale h));retina support *2
		   (glMatrixMode GL_PROJECTION)
       (glLoadIdentity)
       (glScalef 0.1 0.1 1.0)
       (glTranslatef 0.0 -6.0 0.0)
		   (glOrthof -1100.1 0.001 -0.1 0.1 -0.1 1000.0)
       ;(glOrthof -100.0 10.0 -5.0 15.0 -1000.0 1000.0)
      ))
  )

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(random-source-randomize! default-random-source)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define time-step 0.008)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define world (make-world #f #f #f (make-vec 0.0 -10.0) 10))

(is-world world)

(world.clear)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define bomb #f)

(is-body bomb)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (launch-bomb)

  (if (not bomb)
      
      (begin

	(set! bomb (create-body))

	(bomb.set (make-vec 1.0 1.0) 50.0)

	(bomb.friction! 0.2)

	(world.add-body bomb)
	))

  (bomb.position! (make-vec (+ -15.0 (* (random-real) 30.0))
			    15.0))

  (bomb.rotation! (+ -1.5 (* (random-real) 3.0)))

  (bomb.velocity! (n*v -1.5 bomb.position))

  (bomb.angular-velocity! (+ -20.0 (* (random-real) 40.0))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (draw-body body)
  (is-body body)

  (let ((R (angle->mat body.rotation))
	(x body.position)
	(h (n*v 0.5 body.width)))

   (is-vec h)

   (let ((v1 (v+ x (m*v R (make-vec (- h.x) (- h.y)))))
	 (v2 (v+ x (m*v R (make-vec    h.x  (- h.y)))))
	 (v3 (v+ x (m*v R (make-vec    h.x     h.y ))))
	 (v4 (v+ x (m*v R (make-vec (- h.x)    h.y )))))

     (is-vec v1)
     (is-vec v2)
     (is-vec v3)
     (is-vec v4)

     (if (eq? body bomb)
      (glColor4f 0.4 0.9 0.4 1.0)
      (glColor4f 0.8 0.8 0.9 1.0)
   )
    (let ((p (glut-vector 'float (vector v1.x v1.y
                         v2.x v2.y
                         v3.x v3.y
                         v4.x v4.y)) ))
       (glVertexPointer 2  GL_FLOAT  0  p);
       (glEnableClientState GL_VERTEX_ARRAY);
       (glDrawArrays GL_LINE_LOOP  0 4);
       (glDisableClientState GL_VERTEX_ARRAY)
       (glut-unvector p) )

  ))
  )

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (draw-joint joint)

  (is-joint joint)

  (let ((b1 joint.body-1)
	(b2 joint.body-2))

    (is-body b1)
    (is-body b2)

    (let ((x1 b1.position)
	  (x2 b2.position))

      (is-vec x1)
      (is-vec x2)
      
      (let ((p1 (v+ x1 (m*v (angle->mat b1.rotation) joint.local-anchor-1)))
	    (p2 (v+ x2 (m*v (angle->mat b2.rotation) joint.local-anchor-2))))

	(is-vec p1)
	(is-vec p2)

	;(glColor3f 0.5 0.5 0.8)
  (glColor4f 0.5 0.5 0.8 1.0)

  (let ((p (glut-vector 'float (vector 
                          x1.x x1.y
                          p1.x p1.y
                          x2.x x2.y
                          p2.x p2.y)) ))
        (glVertexPointer 2  GL_FLOAT  0  p);
        (glEnableClientState GL_VERTEX_ARRAY);
        (glDrawArrays GL_LINES  0 4);
        (glDisableClientState GL_VERTEX_ARRAY)
        (glut-unvector p) )
  ))))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define b1 #f)
(define b2 #f)
(define b3 #f)
(define b4 #f)
(define b5 #f)
(define b6 #f)

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (set! b1 b)

  (b.set (make-vec 100.0 20.0) FLT-MAX)
  
  (b.position! (make-vec 0.0 -10.0))

  (world.add-body b))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (b.set (make-vec 12.0 0.5) FLT-MAX)
  
  (b.position! (make-vec -1.5 10.0))

  (world.add-body b))

(do ((i 0 (+ i 1)))
    ((>= i 10))

  (let ((b (create-body)))

    (is-body b)
    (is-vec  b.width)

    (b.set (make-vec 0.2 2.0) 10.0)

    (b.position! (make-vec (+ -6.0 (* 1.0 i)) 11.3))

    (b.friction! 0.1)

    (world.add-body b)))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (b.set (make-vec 14.0 0.5) FLT-MAX)

  (b.position! (make-vec 1.0 6.0))

  (b.rotation! 0.3)

  (world.add-body b))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (set! b2 b)

  (b.set (make-vec 0.5 3.0) FLT-MAX)
  
  (b.position! (make-vec -7.0 4.0))

  (world.add-body b))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (set! b3 b)

  (b.set (make-vec 12.0 0.25) 20.0)
  
  (b.position! (make-vec -0.9 1.0))

  (world.add-body b))

(let ((j (create-joint)))

  (is-joint j)

  (j.set b1 b3 (make-vec -2.0 1.0))

  (world.add-joint j))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (set! b4 b)

  (b.set (make-vec 0.5 0.5) 10.0)
  
  (b.position! (make-vec -10.0 15.0))

  (world.add-body b))

(let ((j (create-joint)))

  (is-joint j)

  (j.set b2 b4 (make-vec -7.0 15.0))

  (world.add-joint j))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (set! b5 b)

  (b.set (make-vec 2.0 2.0) 20.0)
  
  (b.position! (make-vec 6.0 2.5))

  (b.rotation! -0.01)

  (b.friction! 0.1)

  (world.add-body b))

(let ((j (create-joint)))

  (is-joint j)

  (j.set b1 b5 (make-vec 6.0 2.6))

  (world.add-joint j))

(let ((b (create-body)))

  (is-body b)
  (is-vec  b.width)

  (set! b6 b)

  (b.set (make-vec 2.0 0.2) 10.0)
  
  (b.position! (make-vec 6.0 3.6))

  (world.add-body b))

(let ((j (create-joint)))

  (is-joint j)

  (j.set b5 b6 (make-vec 7.0 3.5))

  (world.add-joint j))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(buffered-display-procedure
 (lambda ()
   (background 0.0)
   (world.step time-step)
   (for-each draw-body  world.bodies)
   (for-each draw-joint world.joints)
   (collect)

   ))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;(glut-idle (lambda () 
  ;(display "glut-idle\n")
  ;(limit-call-rate 160 (collect))
;  ) )

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;(glutKeyboardFunc
; (lambda (key x y)
;   (case (integer->char key)
;     ((#\space) (launch-bomb)))))

(glut-key-event
 (lambda (event)
   ;(case (glut-event-get event 'keycode)
     ;((#\space) (launch-bomb)))
     (launch-bomb)
     ))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(display "Press <space> to throw the bomb\n")

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(glut-main-loop)
Last Updated: 12/11/2020, 1:11:36 PM